<?php
/**
 * 牌局日志备份和缓存实日志
 * Created by PhpStorm.
 * Keter
 * 2016/8/1
 * @守护进程
 */
class DeductRoomDiamonds extends ScriptBase
{
    /**
     * 扣除钻石队列名
     */
    const QUEEN_NAME = 'deductRoomDiamonds';

    /**
     * 出错备份
     */
    const QUEEN_BACKUP_NAME = 'deductRoomDiamondsBackup';

    /**
     * 当前脚本暂停标志
     * 同类结果为TRUE时则暂停和停止，如1
     */
    const SUSPEND_TAG = 'DEDUCT_ROOM_DIAMONDS_SUSPEND'; //暂停

    /**
     * 停止脚本标志
     */
    const STOP_TAG = 'DEDUCT_ROOM_DIAMONDS_STOP'; //停止

    public $userRedis;
    public $roomStatusRedis;

    /**
     * 逻辑代码
     */
    public function logic()
    {
        set_time_limit(0);

        while (true) {
            try {
                sleep(1);

                // 连接redis
                $this->userRedis  = $this->redis('user_info');
                $this->roomStatusRedis = $this->redis('room_status');

                //停止脚本循环
                if ($this->roomStatusRedis->get(self::STOP_TAG)) {
                    break;
                }

                //暂停脚本循环
                if ($this->roomStatusRedis->get(self::SUSPEND_TAG)) {
                    continue;
                }

                //执行脚本
                $element = $this->roomStatusRedis->lrange(self::QUEEN_NAME, -1, -1);
                if($element) {
                    $result      = $this->handler($element);
                    $lastElement = $this->roomStatusRedis->rpop(self::QUEEN_NAME);
                    /**
                     * 如果执行不成功，则放入备份队列
                     */
                    if ($lastElement && !$result) {
                        $this->roomStatusRedis->lpush(self::QUEEN_BACKUP_NAME, $lastElement);
                    }
                }

                // 断开redis
                $this->deinitRedis('user_info');
                $this->deinitRedis('room_status');
            } catch (Exception $e) {
                $this->e($e->getMessage());
            }
        }
    }

    /**
     * 执行脚本
     * @param $redis
     */
    public function handler($result)
    {
        $result = reset($result);
        $str = $result;

        if  ($str) {
            $data = json_decode($str, true);
            return $this->deductDiamonds($data);
        }

        return false;
    }

    public function deductDiamonds($data)
    {
        if (!(isset($data['roomID']) && $data['roomID'])) {
            $this->e('no_room_id',  $data);
            return false;
        }

        /**
         * 获取房间信息
         */
        $fields = ['serverID', 'roomID', 'gameType', 'totalRound', 'freeDiamond', 'paidDiamond', 'creator'];
        $roomInfo  = $this->roomStatusRedis->hMget('R:' . $data['roomID'], $fields);

        if (!$roomInfo['roomID']) {
            $this->e('no_room',  $data['roomID']);
            return false;
        }

        // server没设置扣除钻石
        if(0 == (int)$roomInfo['freeDiamond'] && 0 == (int)$roomInfo['paidDiamond'])
        {
            $this->e('deductDiamonds_not_set_diamonds', $roomInfo);
        }

        $uKey = 'U:' . $roomInfo['creator'];
        if (!$this->userRedis->exists($uKey)) {
            $this->e('not_exists_user',  $roomInfo['creator']);
            return false;
        }

        /**
         * 获取用户信息
         */
        $userInfo = $this->userRedis->hMget($uKey, [
            'uid', 'nickname', 'platform', 'channelID', 'ver', 'freeDiamond','paidDiamond'
        ]);
        $arr = [
            'freeDiamond' => (integer)$userInfo['freeDiamond'] - (integer)$roomInfo['freeDiamond'],
            'paidDiamond' => (integer)$userInfo['paidDiamond'] - (integer)$roomInfo['paidDiamond'],
        ];

        /** 同步更新到新系统DB */
        $arr['freeDiamond'] = $arr['freeDiamond'] < 0 ? 0 : $arr['freeDiamond'] ;
        $arr['paidDiamond'] = $arr['paidDiamond'] < 0 ? 0 : $arr['paidDiamond'] ;

        $diamond = $this->userRedis->hget($uKey, 'diamond');
        if ($diamond) {
           // $userInfo['diamond'] = $diamond;
            $arr['diamond'] = $arr['freeDiamond'] + $arr['paidDiamond'];
        }

        if ($diamond) {
            $mysql = $this->mysql('game');
            $sql = "UPDATE d_user_status SET freeDiamond = {$arr['freeDiamond']} , paidDiamond = {$arr['paidDiamond']}, diamond = {$arr['diamond']} WHERE uid= {$userInfo['uid']}";
            $mysql->query($sql);
        }
        
        /**
         * 扣减钻石
         */
        $deductTime = time();
        $result = $this->userRedis->hMset($uKey, $arr);
        if ($result) {
            $roomInfo['diamond'] = $roomInfo['freeDiamond'] + $roomInfo['paidDiamond'];
            $this->i('suc_reduce_room_diamond', $roomInfo);
            /**
             * 记入已售房间日志
             */
            $this->writeSaleLog($deductTime, $userInfo, $arr, $roomInfo);
            /**
             * 记入扣减统计日志
             */
            $this->writeDiamondLog($userInfo, $arr, $roomInfo);
            return true;
        } else {
            $this->e('failed_reduce_room_diamond',  $roomInfo);
            return false;
        }
    }

    /**
     * 写入已售房间日志，以便崩溃时的赔付等
     * @param $deductTime
     * @param $userInfo
     * @param $arr
     * @param $roomInfo
     */
    public function writeSaleLog($deductTime, $userInfo, $arr, $roomInfo)
    {
        $data = [
            'serverID'      => $roomInfo['serverID'],//服务器ID
            'roomID'        =>  $roomInfo['roomID'],//房间ID
            'deductTime'    => $deductTime,//房间扣钱时间
            'roomCreator'   => $userInfo['uid'],//创建者ID
            'totalRound'    => $roomInfo['totalRound'], //开局数量
            'realRound'     => 1, //已玩局数
            'diamond'       => $roomInfo['diamond'],//已扣钻石
            'allTotalScore' => json_encode([], JSON_UNESCAPED_UNICODE)
        ];

        $key = 'saleLog:' . $roomInfo['serverID'] . ':' . $roomInfo['roomID'];
        $result = $this->roomStatusRedis->hMset($key, $data);
        if (!$result) {
            $this->e('write_sale_log_error', $data);
        }
    }

    /**
     * 写入钻石赠送队列，以便落地到Mysql
     * @param $userInfo
     * @param $remainDiamond
     * @param $roomInfo
     */
    public function writeDiamondLog($userInfo, $remainDiamond, $roomInfo)
    {
        try {
            $data = [
                'uid' => $userInfo['uid'],
                'type'       => 1, //扣减
                'payType'    => 2, //综合
                'actType'    => 0,
                'gameType'   => $roomInfo['gameType'],
                'platform'   => $userInfo['platform'],
                'channelID'  => $userInfo['channelId'],
                'version'    => $userInfo['ver'],
                'nickname'   => $userInfo['nickname'],
                'diamond'    => $roomInfo['diamond'],
                'oldDiamond' => $userInfo['freeDiamond'] + $userInfo['paidDiamond'],
                'newDiamond' => $remainDiamond['freeDiamond'] + $remainDiamond['paidDiamond'],
                'desc'       => 'deduct_diamond',
                'createTime' => time(),
            ];
            $queen = new DiamondLogQueen();
            $queen->push($data);
        } catch(Exception $e) {
            $this->e('push_diamond_log_error', $data);
        }
    }

    public function addTest()
    {
        $data[] = array(
            'roomID' => '101310',
        );

        $data[] = array(
            'roomID' => '138411',
        );

        foreach($data as $row) {
            $this->roomStatusRedis->lpush(self::QUEEN_NAME, json_encode($row, JSON_UNESCAPED_UNICODE));
        }

        die;
    }
}
?>
